package com.gserver.netty;

import java.util.concurrent.ConcurrentLinkedQueue;

import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.handler.timeout.IdleState;
import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler;
import org.jboss.netty.handler.timeout.IdleStateEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gserver.game.HandlerDispatcher;
import com.gserver.game.domain.MessageQueue;
import com.gserver.netty.domain.Message;

/**
 * 游戏协议接收分发器
 */
public class ServerHandler extends IdleStateAwareChannelHandler {
	public Logger log = LoggerFactory.getLogger(this.getClass());
	public static HandlerDispatcher handlerDispatcher;

	public void init() {
		new Thread(handlerDispatcher).start();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.jboss.netty.channel.SimpleChannelUpstreamHandler#channelConnected
	 * (org.jboss.netty.channel.ChannelHandlerContext,
	 * org.jboss.netty.channel.ChannelStateEvent) 建立一个新channel
	 */
	@Override
	public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
			throws Exception {
		log.debug("进来一个channel：" + ctx.getChannel().getId());
		MessageQueue messageQueue = new MessageQueue(
				new ConcurrentLinkedQueue<Message>());
		handlerDispatcher.addMessageQueue(ctx.getChannel().getId(),
				messageQueue);

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.jboss.netty.channel.SimpleChannelUpstreamHandler#channelDisconnected
	 * (org.jboss.netty.channel.ChannelHandlerContext,
	 * org.jboss.netty.channel.ChannelStateEvent) 玩家主动关闭channel
	 */
	@Override
	public void channelDisconnected(ChannelHandlerContext ctx,
			ChannelStateEvent e) throws Exception {
		log.error("关掉一个channel：" + ctx.getChannel().getId());
		handlerDispatcher.removeMessageQueue(e.getChannel().getId().toString());
		e.getChannel().close();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.jboss.netty.channel.SimpleChannelUpstreamHandler#exceptionCaught(
	 * org.jboss.netty.channel.ChannelHandlerContext,
	 * org.jboss.netty.channel.ExceptionEvent) 玩家被动关闭channel
	 */
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
			throws Exception {
		log.error("出异常啦……" + ctx.getChannel().getId());
		 e.getCause().printStackTrace();
		handlerDispatcher.removeMessageQueue(e.getChannel().getId().toString());
		e.getChannel().close();
	}

	@Override
	public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e)
			throws Exception {
		if (e.getState()==IdleState.WRITER_IDLE) {
			log.info("server writer idle:"+e.getChannel().getId());
		}
		if (e.getState() == IdleState.ALL_IDLE) {
			log.info("server channelIdle:"+e.getChannel().getId());
			handlerDispatcher.removeMessageQueue(e.getChannel().getId().toString());
			e.getChannel().close();
		}
//			super.channelIdle(ctx, e);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.jboss.netty.channel.SimpleChannelUpstreamHandler#messageReceived(
	 * org.jboss.netty.channel.ChannelHandlerContext,
	 * org.jboss.netty.channel.MessageEvent) 消息接收处理器
	 */
	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
			throws Exception {
		Message msg = null;
		try {
			msg = (Message) e.getMessage();
		} catch (Exception e1) {

			log.error("分发异常", e1);
			super.messageReceived(ctx, e);
		}

		// 通知回调协议
		handlerDispatcher.addMessage(msg);
	}

	public HandlerDispatcher getHandlerDispatcher() {
		return handlerDispatcher;
	}

	public void setHandlerDispatcher(HandlerDispatcher handlerDispatcher) {
		ServerHandler.handlerDispatcher = handlerDispatcher;
	}

}
